package flib;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.Graphics2D;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Vector;

import processing.core.*;
import processing.pdf.PGraphicsPDF;
import com.lowagie.text.Document;
import com.lowagie.text.PageSize;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfWriter;

import simpleGeom.Bounds2D;
import simpleGeom.OBJExporter;
import simpleGeom.Rect2D;
import simpleGeom.Vec2D;
import simpleGeom.Vec3D;
import simpleGui.FileHelper;
import simpleGui.PCam2DGraphics;

public class FloorplanBrowser extends PApplet implements ActionListener {
	Vector<Plan> floorplans = new Vector<Plan>();
	
	PFont font;
	String path = "/Users/administrator/projekte/Doktor/work/Floorplans/drawings/SVG";
	String pathBuildings = "/Users/administrator/projekte/Doktor/work/Floorplans/drawings/Buildings";
	PCam2DGraphics cam;
	final static int COLD = 0;
	final static int GROUP = 1;
	float strokeCut = 0.02f;
	float strokeView = 0.02f;
	Plan plan;
	int iPlan;
	int iLevel;
	int colorModeRoom = GROUP;

	Vector<File> files;
	FloorplanLoader2D loader;
	boolean flagChange = false;
	boolean flagLoad =false;

	public void setup() {
		size(1600, 900);
		loadData();
		/*
		 * loadFiles(); */
		 
		 font=this.createFont("arial", 0.5f);
		this.textFont(font,12);
		
		//println(floorplans.size());
		 
		smooth();
		// writeItext();
		// saveObj(bubbles[0]);
		// renderPlan(bubbles[0]);
		// savePDF();
		setupMenu();
		cam = new PCam2DGraphics(this);
		// savePDF2();
		// saveBuildings();
		loadPlan(files.get(0));
	}

	public void setupMenu() {
		Frame frame = findFrame();
		MenuBar myMenu = new MenuBar();
		Menu topButton = new Menu("Box");
		MenuItem item1 = new MenuItem("New Box");
		topButton.add(item1);
		item1.addActionListener(this);
		MenuItem item2 = new MenuItem("Delete Box");
		item2.addActionListener(this);
		topButton.add(item2);
		myMenu.add(topButton);
		frame.setMenuBar(myMenu);
	}

	public Frame findFrame() {
		Container f = this.getParent();
		while (!(f instanceof Frame) && f != null)
			f = f.getParent();
		return (Frame) f;
	}

	public void checkPlan(Plan plan) {
		for (int i = 0; i < plan.rooms.size(); i++) {
			FlibFace room = plan.rooms.get(i);
			if (room.getFaceNodes().size() < 3) {
				println("check" + plan.path);
				println("room has not enough points");
			}
		}
	}

	public void loadData() {
		loader = new FloorplanLoader2D(new File("/Users/administrator/Documents/workspace/FrameWork1308P2/flibConfig.xml"));
		
		files = FileHelper.getFilesFromFolder(pathBuildings, ".obj");
		files = FileHelper.getFilesFromFolder(path, ".svg");
	}

	public void loadPlan(File file) {
		
		if (file.getName().endsWith(".obj")) {
			plan = loader.loadFromOBJ(this, file.getAbsolutePath());
		} else {
			plan = loader.loadFloorplanSVG(file);
		}
		println(files.get(iPlan).getName());
		plan.assignGroups();
		checkPlan(plan);
	}

	public void drawSinglePlan(PGraphics g) {

		FlibGraph group = plan.levels.firstElement();
		group.assignGroups();

		Rect2D bds = group.getBounds2D();
		group.translate(-bds.getCenterX(), -bds.getCenterY());
		g.translate(g.width * 0.5f, g.height * 0.5f);
		g.scale(30);
		g.noStroke();
		randomSeed(1);
		g.colorMode(HSB, 255);
		//g.colorMode(RGB, 255);
		
		for (int i = 0; i < group.rooms.size(); i++) {
			FlibFace room = group.rooms.get(i);
			fill(255,0,255);
			if (room.isCold()) {
				g.fill(200);
			} else if (room.isPublic()) {
				g.fill(170);
			} else {
				g.fill(230);
			}

			if (colorModeRoom == GROUP) {
				g.fill(255f*room.groupId/group.nGroups, 255, 255);
				//g.fill(200);
				// noFill();

				// translate(random(0.3f),random(0.3f));
				if (room.isPublic()) {
					g.fill(255,40,255);
				}
			} else if (colorModeRoom == COLD) {
				if (room.isCold()) {
					g.fill(100);
				} else {
					g.fill(0);
				}
			}
			room.display(g);
		}
		g.colorMode(RGB, 255);
		for (int i = 0; i < group.walls.size(); i++) {
			FlibWall wall = group.walls.get(i);
			wall.construct();
		}
		for (int i = 0; i < group.walls.size(); i++) {
			FlibWall wall = group.walls.get(i);
			if (wall.isHelper()) {
				//wall.drawView(g);
			}
		}
		for (int i = 0; i < group.walls.size(); i++) {
			FlibWall wall = group.walls.get(i);
			if (!wall.isCut()) {
				wall.fill(g);
			}
		}
		for (int i = 0; i < group.walls.size(); i++) {
			FlibWall wall = group.walls.get(i);
			if (!wall.isCut() && !wall.isHelper()) {
			//	wall.drawView(g);
			}
		}
		for (int i = 0; i < group.walls.size(); i++) {
			FlibWall wall = group.walls.get(i);
			if (wall.isCut()) {
				wall.fill(g);
			}
		}
		for (int i = 0; i < group.walls.size(); i++) {
			FlibWall wall = group.walls.get(i);
			if (wall.isCut()) {
				//wall.drawView(g);
				//wall.drawCut(g);
			}
		}

		stroke(255, 0, 0);
		noFill();
		for (int i = 0; i < group.rooms.size(); i++) {
			FlibFace room = group.rooms.get(i);
			if (room.getArea2D() < 0.01) {
				room.getBounds2D().display(g);
			}
		}
		stroke(0);
		for (int i = 0; i < group.walls.size(); i++) {
			FlibWall wall = group.walls.get(i);
			if (wall.type.label.equals("wall-help") && wall.test) {
				// wall.drawView(g);
			}
		}
		stroke(255, 255, 0);
		/*
		 * for (int i=0;i<group.rooms.size();i++){ Room room=group.rooms.get(i);
		 * if (room.getArea2D()>0.01){ room.getBounds2D().display(g); } }
		 */
		// plan.displayDetail(g);
	}

	public void saveBuildings() {
		int sumRooms = 0;
		FloorplanLoader2D loader = new FloorplanLoader2D(new File("/Users/administrator/Documents/workspace/FrameWork1308P2/flibConfig.xml"));
		
		Vector<File> files = FileHelper.getFilesFromFolder(path, ".svg");
		for (int i = 0; i < files.size(); i++) {
			File file = files.get(i);
			plan = loader.loadFloorplanSVG(file);
			plan.assignGroups();
			sumRooms += plan.rooms.size();
			for (int ii = 0; ii < plan.nLevels; ii++) {
				FlibGraph level = plan.levels.get(ii);
				level.assignBuildings();
	
				for (int iii = 0; iii < level.nBuildings; iii++) {
					Vector<FlibHENode> nodes = new Vector<FlibHENode>();
					Vector<FlibWall> walls = new Vector<FlibWall>();
					Vector<FlibFace> rooms = new Vector<FlibFace>();
					for (int j = 0; j < level.rooms.size(); j++) {
						FlibFace room = level.rooms.get(j);
						if (room.buildingId == iii) {
							if (room.getFaceNodes().size() > 2) {
								rooms.add(room);
							}
						}
					}
					for (int j = 0; j < level.nodes.size(); j++) {
						FlibHENode n = level.nodes.get(j);
						if (n.buildingId == iii) {
							nodes.add(n);
						}
					}
					for (int j = 0; j < level.walls.size(); j++) {
						FlibWall wall = level.walls.get(j);
						if (wall.buildingId == iii) {
							walls.add(wall);
						}
					}
					String path = file.getName();
					path.replaceAll(".svg", "");
					path += "_level" + ii + "_building" + iii + ".obj";
					path = pathBuildings + "/" + path;
	
					FloorplanLoader2D.saveAsGraph(nodes, walls, rooms,
							new File(path));
				}
			}
		}
		println("sumRooms: " + sumRooms);
	}

	

	public void savePDF2() {
		font = this.createDefaultFont(10);
		int w = (int) com.lowagie.text.PageSize.A4.getWidth();
		int h = (int) com.lowagie.text.PageSize.A4.getHeight();
		PGraphicsPDF pdf = (PGraphicsPDF) createGraphics(w, h, PDF,
				this.selectOutput());
		pdf.beginDraw();
		pdf.textFont(font, 0.5f);
		pdf.strokeWeight(0.2f);
		for (int i = 0; i < 300; i++) {
			iPlan = i;
			loadPlan(files.get(iPlan));
			drawSinglePlan(pdf);
			pdf.text("pfad" + path, 10, 10);
			pdf.noFill();
			pdf.nextPage();
		}
		
		pdf.endDraw();
		pdf.dispose();
		println("saved");
	}

	

	public void draw() {
		if (flagChange) {
			flagChange = false;
			loadPlan(files.get(iPlan));
		}
		if (flagLoad) {
			loadPlan(new File(selectInput()));
			flagLoad=false;
		}
		g.background(255);
		g.stroke(0);
		g.fill(0);
		g.text(plan.path, 50, 50);
		g.pushMatrix();
		cam.useCam(g);
		drawSinglePlan(g);
		g.popMatrix();

	}


	

	

	public void drawAsText(Plan plan, PGraphics g) {
		g.textAlign(CENTER);
		for (int i = 0; i < plan.rooms.size(); i++) {
			FlibFace room = plan.rooms.get(i);
			if (room.isPublic()) {
				// g2d.fill(200,0,0);
			} else {
				// g2d.fill(100,0,0);
			}
			if (room.isCold()) {
				// g2d.fill(100,100,255);
			}
			Vec3D center = room.getGravityCenter();
			g.text("room", center.x, center.y);

		}
		// g2d.stroke(255,0,0);
		for (int i = 0; i < plan.walls.size(); i++) {
			FlibWall wall = plan.walls.get(i);
			String txt = "wall";
			if (wall.type != null) {
				txt = wall.type.label;
				txt = txt.replaceFirst("wall-", "");
			}
			g.pushMatrix();
			g.translate(wall.cX(), wall.cY());
			g.text(txt, 0, 0);
			g.popMatrix();
		}

	}

	

	

	public void keyPressed() {
		if (key == 'i') {
			iPlan++;
			if (iPlan >= files.size()) {
				iPlan = 0;
			}
			flagChange = true;
		}
		if (key == 'j') {
			iPlan--;
			if (iPlan<0){
				iPlan=files.size()-1;
			}
			flagChange = true;
		}
		if (key == 'l') {
			flagLoad = true;
		}
	}

	@Override
	public void actionPerformed(ActionEvent arg0) {
		// TODO Auto-generated method stub
	}
	String selectedFile;
	String selectOutput(){
		this.selectOutput("Select a file to process:", "fileSelected");
		return selectedFile;
	}
	String selectInput(){
		
		this.selectInput("Select a file to process:", "fileSelected");
		return selectedFile;
	}
	
	public void fileSelected(File selection) {
		  if (selection == null) {
		    println("Window was closed or the user hit cancel.");
		    selectedFile=null;
		  } else {
			  selectedFile= selection.getAbsolutePath();
		    println("User selected " + selection.getAbsolutePath());
		  }
		}
	

}
